﻿using System;
using SkiaSharp;
using System.Collections;
using FlowChartV2.Libraries;

namespace FlowChartV2
{
    class Program
    {
        const int interval = 50;
        static List<Stack> li = new List<Stack>();
        static void Main()
        {
            SKImageInfo imageInfo = new SKImageInfo(5000, 5000);
            using (SKSurface surface = SKSurface.Create(imageInfo))
            {
                SKCanvas canvas = surface.Canvas;
                canvas.DrawColor(SKColors.White);
                SKPaint paint = new SKPaint();
                paint.Color = SKColors.Black;
                paint.IsAntialias = true;
                paint.StrokeWidth = 1;
                paint.Style = SKPaintStyle.Stroke;
                List<Stack> li = Convert();
                Draw(li, ref canvas, paint);
                // RoundRec rrect = new RoundRec(new Point(150, 5), "Begin");
                // rrect.Draw(ref canvas, paint);
                // rrect.DrawText(ref canvas, paint);
                // Rect rect = new Rect(new Point(150, rrect.bottom.y + 10), "x = 5");
                // rect.Draw(ref canvas, paint);
                // rect.DrawText(ref canvas, paint);
                // // rrect.DrawPoints(ref canvas, paint);
                // // rect.DrawPoints(ref canvas, paint);
                // Line line = new Line(rrect, rect);
                // Hexagon hex = new Hexagon(new Point(150, rect.bottom.y + 10), "i = 0; i < a; i++");
                // hex.Draw(ref canvas, paint);
                // hex.DrawText(ref canvas, paint);
                // rect = new Rect(new Point(150, hex.bottom.y + 10), "q += 10;");
                // rect.Draw(ref canvas, paint);
                // rect.DrawText(ref canvas, paint);
                // // line.Draw(ref canvas, paint);
                // // line = new Line(rect, hex);
                // // line.Draw(ref canvas, paint);
                // Lines lines = new Lines(rect, hex);
                // lines.DrawLeft(ref canvas, paint);
                // CurvRect crect = new CurvRect(new Point(150, rect.bottom.y + 30), "Hello world from past to future");
                // crect.Draw(ref canvas, paint);
                // crect.DrawText(ref canvas, paint);
                // Lines lines2 = new Lines(hex, crect);
                // lines2.DrawRight(ref canvas, paint);
                // Figure f = new Rect(new Point(0, 0), "");
                // foreach (var i in li)
                // {
                //     switch (i.type)
                //     {
                //         case 2:
                //             {

                //             }
                //             break;
                //         case 3:
                //             {
                //                 f = new Rect(new Point(x, y), i.text);
                //             }
                //             break;
                //         case 4:
                //             {
                //                 f = new Rhombus(new Point(x, y), i.text);
                //             }
                //             break;
                //         case 5:
                //             {
                //                 f = new Hexagon(new Point(x, y), i.text);
                //             }
                //             break;
                //         case 6:
                //             {
                //                 f = new Rhombus(new Point(x, y), i.text);
                //             }
                //             break;
                //         case 7:
                //             {
                //                 f = new CurvRect(new Point(x, y), i.text);
                //             }
                //             break;
                //     }
                //     f.Draw(ref canvas, paint);
                //     f.DrawText(ref canvas, paint);
                //     y += f.size.h + 20;
                // }
                using (var image = surface.Snapshot())
                using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
                using (var stream = File.OpenWrite("out.png"))
                {
                    data.SaveTo(stream);
                }
            }
        }
        static List<Stack> Convert()
        {
            int x = 2500, y = 10;
            StreamReader reader = new StreamReader(File.Open("in.txt", FileMode.Open));
            List<Stack> li = new List<Stack>();
            string line = "", text = "";
            Stack stack = new Stack();
            stack.childs = new List<Stack>();
            stack.figure = new RoundRec(new Point(x, y), "Begin");
            li.Add(stack);
            y += stack.figure.size.h + interval;
            li = Recurse(li, ref reader, x, ref y);
            return li;
        }
        static void Draw(List<Stack> li, ref SKCanvas canvas, SKPaint paint)
        {
            foreach (var i in li)
            {
                i.figure.Draw(ref canvas, paint);
                i.figure.DrawText(ref canvas, paint);
                if (i.childs.Count > 0)
                    Draw(i.childs, ref canvas, paint);
            }
        }
        static List<Stack> Recurse(List<Stack> li, ref StreamReader reader, int x,ref int y)
        {
            Figure figure;
            string[] splited;
            string line, text;
            int i = 0,t;
            bool getInside = false;
            while ((line = reader.ReadLine()) != null)
            {
                t = x;
                splited = line.Split(' ');
                if (splited.FirstOrDefault(p => p == "}") != null)
                {
                    return li;
                }
                if (splited.FirstOrDefault(p => p == "for" || p == "while") != null)
                {
                    text = getIns(line, '(', ')');
                    figure = new Hexagon(new Point(x, y), text);
                    getInside = true;
                }
                else if (splited.FirstOrDefault(p => p == "if") != null)
                {
                    text = getIns(line, '(', ')');
                    figure = new Rhombus(new Point(x, y), text);
                    getInside = true;
                    t += figure.size.w + 10;
                }
                else
                {
                    figure = new Rect(new Point(x, y), line);
                }
                li.Add(new Stack() { figure = figure, childs = new List<Stack>() });
                y += figure.size.h + interval;
                if (getInside)
                {
                    List<Stack> childs = new List<Stack>();
                    childs = Recurse(childs, ref reader, t, ref y);
                    li[i].childs = childs;
                }
                getInside = false;
                i++;
            }
            return li;
        }
        static string getIns(string text, char start, char? end = null)
        {
            int s = text.IndexOf(start), e = end == null ? text.Length : text.IndexOf((char)end);
            return text.Substring(s + 1, e - s - 1).ToString();
        }
    }
    // class Node
    // {
    //     public Node node { get; set; }
    //     public Node child { get; set; }
    //     public Stack stack { get; set; }
    // }
    class Stack
    {
        public Figure figure { get; set; }
        public List<Stack> childs { get; set; }
        public Stack(Figure figure, List<Stack> childs)
        {
            this.figure = figure;
            this.childs = childs;
        }
        public Stack()
        {

        }
    }
}
